const moment = require('moment')
const Controller = require('egg').Controller

class BillController extends Controller {
  async add() {
    const { ctx, app } = this

    const { amount, date, type_id, type_name, pay_type, remark } =
      ctx.request.body
    // console.log(ctx.request.body)

    if (!amount || !date || !type_id || !type_name || !pay_type) {
      ctx.body = {
        code: 400,
        msg: '参数错误',
        data: null,
      }
      return
    }

    try {
      const token = ctx.request.header.authorization
      const decode = app.jwt.verify(token, app.config.jwt.secret)
      let user_id
      if (decode && decode.id) {
        user_id = decode.id
      }

      const billItem = {
        amount,
        user_id,
        type_id,
        type_name,
        pay_type,
        remark,
        date: Date.now(),
      }

      const result = ctx.service.bill.addBill(billItem)
      if (result) {
        ctx.body = {
          code: 200,
          msg: '添加成功',
          data: null,
        }
      } else {
        ctx.body = {
          code: 500,
          msg: '添加失败',
          data: null,
        }
      }
    } catch (error) {
      console.log('add bill service', error)
      ctx.body = {
        code: 500,
        msg: '系统错误',
      }
    }
  }

  /**
   * 获取用户账单 列表
   * query中参数，date, page, page_size, type_id 没有就不要加
   */
  async getBillList() {
    const { ctx, app } = this
    const { date, page = 1, page_size = 10, type_id = 'all' } = ctx.query

    try {
      let user_id
      const token = ctx.request.header.authorization
      const decode = app.jwt.verify(token, app.config.jwt.secret)
      if (!decode) return

      user_id = decode.id
      // console.log('date', date)
      const list = await ctx.service.bill.getDataByUserId(user_id)

      const _list = list.filter((item) => {
        const itemDate = moment(Number(item.date)).format('YYYY-MM')
        // console.log(
        //   itemDate,
        //   moment(Number(item.date)).format('YYYY-MM') == date
        // )
        if (type_id != 'all') {
          return itemDate == date && type_id == item.type_id
        } else {
          return itemDate == date
        }
      })
      // console.log('list ', _list)
      // console.log('list ', list)
      // 格式化数据，将其变成我们之前设置好的对象格式
      let listMap = _list
        .reduce((curr, item) => {
          // console.log(curr)
          // console.log(item)
          // curr 默认初始值是一个空数组 []
          // 把第一个账单项的时间格式化为 YYYY-MM-DD
          const date = moment(Number(item.date)).format('YYYY-MM-DD')
          // const originDate = item.date
          // console.log(date)

          // 如果能在累加的数组中找到当前项日期 date，那么在数组中的加入当前项到 bills 数组。
          if (
            curr &&
            curr.length &&
            curr.findIndex((item) => item.date == date) > -1
          ) {
            const index = curr.findIndex((item) => item.date == date)
            curr[index].bills.push(item)
          }
          // 如果在累加的数组中找不到当前项日期的，那么再新建一项。
          if (
            curr &&
            curr.length &&
            curr.findIndex((item) => item.date == date) == -1
          ) {
            curr.push({
              date,
              bills: [item],
            })
          }
          // 如果 curr 为空数组，则默认添加第一个账单项 item ，格式化为下列模式
          if (!curr.length) {
            curr.push({
              date,
              bills: [item],
            })
          }
          // console.log('curr', curr)
          return curr
        }, [])
        .sort((a, b) => moment(b.date) - moment(a.date)) // 时间顺序为倒叙，时间约新的，在越上面
      // console.log('listMap', listMap)
      // 分页处理，listMap 为我们格式化后的全部数据，还未分页。
      const filterListMap = listMap.slice(
        (page - 1) * page_size,
        page * page_size
      )

      // 计算当月总收入和支出
      // 首先获取当月所有账单列表
      let __list = list.filter(
        (item) => moment(Number(item.date)).format('YYYY-MM') == date
      )
      // 累加计算支出
      let totalExpense = __list.reduce((curr, item) => {
        if (item.pay_type == 1) {
          curr += Number(item.amount)
          return curr
        }
        return curr
      }, 0)
      // 累加计算收入
      let totalIncome = __list.reduce((curr, item) => {
        if (item.pay_type == 2) {
          curr += Number(item.amount)
          return curr
        }
        return curr
      }, 0)

      // 返回数据
      ctx.body = {
        code: 200,
        msg: '请求成功',
        data: {
          totalExpense, // 当月支出
          totalIncome, // 当月收入
          totalPage: Math.ceil(listMap.length / page_size), // 总分页
          list: filterListMap || [], // 格式化后，并且经过分页处理的数据
        },
      }
    } catch (error) {
      console.log('getBillList', error)
      ctx.body = {
        code: 500,
        msg: '系统错误',
        data: null,
      }
    }
  }

  // 获取账单详情
  async detail() {
    const { ctx, app } = this
    // 获取账单 id 参数
    const { id = '' } = ctx.query
    // 获取用户 user_id
    let user_id
    const token = ctx.request.header.authorization
    // 获取当前用户信息
    const decode = await app.jwt.verify(token, app.config.jwt.secret)
    if (!decode) return
    user_id = decode.id
    // 判断是否传入账单 id
    if (!id) {
      ctx.body = {
        code: 500,
        msg: '订单id不能为空',
        data: null,
      }
      return
    }

    try {
      // 从数据库获取账单详情
      const detail = await ctx.service.bill.detail(id, user_id)
      ctx.body = {
        code: 200,
        msg: '请求成功',
        data: detail,
      }
    } catch (error) {
      ctx.body = {
        code: 500,
        msg: '系统错误',
        data: null,
      }
    }
  }

  // 编辑账单
  async editBill() {
    const { ctx, app } = this
    // 账单的相关参数，这里注意要把账单的 id 也传进来
    const {
      id,
      amount,
      type_id,
      type_name,
      date,
      pay_type,
      remark = '',
    } = ctx.request.body
    // 判空处理
    if (!amount || !type_id || !type_name || !date || !pay_type) {
      ctx.body = {
        code: 400,
        msg: '参数错误',
        data: null,
      }
    }

    try {
      let user_id
      const token = ctx.request.header.authorization
      const decode = await app.jwt.verify(token, app.config.jwt.secret)
      if (!decode) return
      user_id = decode.id
      // 根据账单 id 和 user_id，修改账单数据
      const result = await ctx.service.bill.update({
        id, // 账单 id
        amount, // 金额
        type_id, // 消费类型 id
        type_name, // 消费类型名称
        date, // 日期
        pay_type, // 消费类型
        remark, // 备注
        user_id, // 用户 id
      })
      ctx.body = {
        code: 200,
        msg: '请求成功',
        data: null,
      }
    } catch (error) {
      ctx.body = {
        code: 500,
        msg: '系统错误',
        data: null,
      }
    }
  }

  async deleteBillItem() {
    const { ctx, app } = this
    const { id } = ctx.query

    if (!id) {
      ctx.body = {
        code: 400,
        msg: '参数错误',
        data: null,
      }
    }

    try {
      let user_id
      const token = ctx.request.header.authorization
      const decode = await app.jwt.verify(token, app.config.jwt.secret)
      if (!decode) return
      user_id = decode.id
      const result = await ctx.service.bill.delete(id, user_id)
      ctx.body = {
        code: 200,
        msg: '请求成功',
        data: null,
      }
    } catch (error) {
      ctx.body = {
        code: 500,
        msg: '系统错误',
        data: null,
      }
    }
  }

  /**
   * 统计数据 需要的 list 数据
   */
  async summaryData() {
    const { ctx, app } = this
    const { date } = ctx.query

    try {
      let user_id
      const token = ctx.request.header.authorization
      const decode = app.jwt.verify(token, app.config.jwt.secret)
      if (!decode) return

      user_id = decode.id
      // console.log('date', date)
      const list = await ctx.service.bill.getDataByUserId(user_id)

      // 根据时间参数，筛选出当月所有的账单数据
      const start = moment(date).startOf('month').unix() * 1000 // 选择月份，月初时间
      const end = moment(date).endOf('month').unix() * 1000 // 选择月份，月末时间
      const _data = list.filter(
        (item) => Number(item.date) > start && Number(item.date) < end
      )

      // 累加计算支出
      let total_expense = _data.reduce((curr, item) => {
        if (item.pay_type == 1) {
          curr += Number(item.amount)
          return curr
        }
        return curr
      }, 0)
      // 累加计算收入
      let total_income = _data.reduce((curr, item) => {
        if (item.pay_type == 2) {
          curr += Number(item.amount)
          return curr
        }
        return curr
      }, 0)
      // 获取收支构成
      let total_data = _data.reduce((arr, cur) => {
        const index = arr.findIndex((item) => item.type_id == cur.type_id)
        if (index == -1) {
          arr.push({
            type_id: cur.type_id,
            type_name: cur.type_name,
            pay_type: cur.pay_type,
            number: Number(cur.amount),
          })
        }
        if (index > -1) {
          arr[index].number += Number(cur.amount)
        }
        return arr
      }, [])

      total_data = total_data.map((item) => {
        item.number = Number(Number(item.number).toFixed(2))
        return item
      })

      // 返回数据
      ctx.body = {
        code: 200,
        msg: '请求成功',
        data: {
          total_expense: Number(total_expense).toFixed(2), // 当月支出
          total_income: Number(total_income).toFixed(2), // 当月收入
          total_data,
        },
      }
    } catch (error) {
      console.log('getBillList', error)
      ctx.body = {
        code: 500,
        msg: '系统错误',
        data: null,
      }
    }
  }
}

module.exports = BillController
